﻿using Songhay.DataAccess.Models;
using Songhay.DataAccess.Models.Extensions;
using Songhay.Extensions;
using Songhay.Mvvm.Models;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;

namespace Songhay.Mvvm.ViewModels
{
    using Extensions;

    /// <summary>
    /// GenericWeb Document for MVVM
    /// </summary>
    [MetadataType(typeof(DocumentMetadata))]
    public partial class DocumentViewModel : BindableBaseWithValidation, IDocument
    {
        public DocumentViewModel()
        {
            var dataType = typeof(DocumentViewModel);
            this.SupportMetadataTypeAttribute(dataType);

            this.Fragments = new ObservableCollection<FragmentViewModel>();
        }

        public DocumentViewModel(Document data)
            : this()
        {
            if (data == null) throw new ArgumentNullException("The expected data is not here.");
            this._data = data;

            this.UpdateViewModel<Document, IDocument>(this._data);

            if (this._data.Fragments == null) return;
            this._data.Fragments.ForEachInEnumerable(i => this.Fragments.Add(new FragmentViewModel(i)));

            this.PropertyChanged += (s, args) =>
            {
                this.UpdateModel<IDocument, Document>(this._data, args.PropertyName);
                var payload = new ModelEventPayload<Document> { Model = this._data, IsUpdate = true };
                CorePrismEvents.ModelEventForDocument.Publish(payload);
            };
        }

        public string ClientId
        {
            get { return this._clientId; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._clientId, value);
            }
        }

        public DateTime? CreateDate
        {
            get { return this._createDate; }
            set { this.SetProperty(ref this._createDate, value); }
        }

        public int DocumentId
        {
            get { return this._documentId; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._documentId, value);
            }
        }

        public string DocumentShortName
        {
            get { return this._documentShortName; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._documentShortName, value);
            }
        }

        public string FileName
        {
            get { return this._fileName; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._fileName, value);
            }
        }

        public ObservableCollection<FragmentViewModel> Fragments
        {
            get { return this._fragments; }
            set { this.SetProperty(ref this._fragments, value); }
        }

        public bool? IsActive
        {
            get { return this._isActive; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._isActive, value);
            }
        }

        public bool? IsRoot
        {
            get { return this._isRoot; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._isRoot, value);
            }
        }

        public DateTime? ModificationDate
        {
            get { return this._modificationDate; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._modificationDate, value);
            }
        }

        public string Path
        {
            get { return this._path; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._path, value);
            }
        }

        public int? SegmentId
        {
            get { return this._segmentId; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._segmentId, value);
            }
        }

        public byte? SortOrdinal
        {
            get { return this._sortOrdinal; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._sortOrdinal, value);
            }
        }

        public string Tag
        {
            get { return this._tag; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._tag, value);
            }
        }

        public int? TemplateId
        {
            get { return this._templateId; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._templateId, value);
            }
        }

        public string Title
        {
            get { return this._title; }
            set
            {
                this.ValidateProperty(this, value);
                this.SetProperty(ref this._title, value);
            }
        }

        public override string ToString()
        {
            return this.ToDisplayText();
        }

        string _clientId;
        DateTime? _createDate;
        int _documentId;
        string _documentShortName;
        string _fileName;
        bool? _isActive;
        bool? _isRoot;
        DateTime? _modificationDate;
        string _path;
        int? _segmentId;
        byte? _sortOrdinal;
        string _tag;
        int? _templateId;
        string _title;

        Document _data;
        ObservableCollection<FragmentViewModel> _fragments;
    }
}